package com.harmontronics.hanma.paas.paas.domain.iam.service;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.UserGroupData;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.UserGroupDataQuery;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.valueobject.HmUserGroupDataFields;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.persistence.HmDataTypeRepository;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.persistence.HmUserGroupDataRepository;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.HmUserGroupData;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.po.HmDataTypePO;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.po.HmUserGroupManagePO;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.po.HmUserGroupMemberPO;
import com.harmontronics.hanma.paas.paas.domain.organization.service.HmOrgService;
import com.harmontronics.hanma.paas.paas.utils.MyBeanUtils;
import com.harmontronics.hanma.paas.paas.utils.StringUtil;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.harmontronics.hanma.paas.paas.domain.iam.repository.mapper.HmUserGroupDataMapper;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.po.HmUserGroupDataPO;
import java.util.List;

@Service("hmUserGroupDataService")
@DS("#header.App-Unique")
public class HmUserGroupDataService{

    @Autowired
    private HmUserGroupDataRepository hmUserGroupDataRepository;

    @Autowired
    private HmUserGroupDataMapper hmUserGroupDataMapper;

    @Autowired
    private HmDataTypeRepository hmDataTypeRepository;

    @Autowired
    private HmUserGroupManageService hmUserGroupManageService;

    @Autowired
    private HmUserGroupMemberService hmUserGroupMemberService;

    @Autowired
    private HmDataTypeService hmDataTypeService;

    @Autowired
    private HmOrgService hmOrgService;

    public void create(UserGroupData groupDataCreateDto) {
        List<String> vals = groupDataCreateDto.getVals();
        if (CollectionUtils.isNotEmpty(vals)) {
            for (String val : vals) {
                QueryWrapper<HmUserGroupDataPO> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq(HmUserGroupDataFields.SCOPE, groupDataCreateDto.getScope());
                queryWrapper.eq(HmUserGroupDataFields.USER_GROUP_ID, groupDataCreateDto.getUserGroupId());
                queryWrapper.eq(HmUserGroupDataFields.DATA_TYPE_ID, groupDataCreateDto.getDataTypeId());
                queryWrapper.isNull(HmUserGroupDataFields.VAL);
                HmUserGroupDataPO userGroupData = hmUserGroupDataMapper.selectOne(queryWrapper);
                if (userGroupData != null) {
                    userGroupData.setVal(val);
                    hmUserGroupDataMapper.updateById(userGroupData);
                } else {

                    HmUserGroupDataPO userGroupData2 = BeanUtil.toBean(groupDataCreateDto, HmUserGroupDataPO.class);
                    userGroupData2.setVal(val);
                    insertSingleGroupData(userGroupData2);
                }
            }
        }
    }



    public void remove(String scope, Integer dataTypeId, Integer userGroupId) {
        QueryWrapper<HmUserGroupDataPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(HmUserGroupDataFields.SCOPE, scope);
        queryWrapper.eq(HmUserGroupDataFields.USER_GROUP_ID, userGroupId);
        queryWrapper.eq(HmUserGroupDataFields.DATA_TYPE_ID, dataTypeId);
        hmUserGroupDataMapper.delete(queryWrapper);
    }

    public void remove(String scope, Integer dataTypeId, Integer userGroupId, String val) {
        QueryWrapper<HmUserGroupDataPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(HmUserGroupDataFields.SCOPE, scope);
        queryWrapper.eq(HmUserGroupDataFields.USER_GROUP_ID, userGroupId);
        queryWrapper.eq(HmUserGroupDataFields.DATA_TYPE_ID, dataTypeId);
        List<HmUserGroupDataPO> list = hmUserGroupDataMapper.selectList(queryWrapper);
        if (list.size() > 1) {
            queryWrapper.eq(HmUserGroupDataFields.VAL, val);
            hmUserGroupDataMapper.delete(queryWrapper);
        } else if(list.size() == 1){
            HmUserGroupDataPO data = list.get(0);
            data.setVal(null);
            hmUserGroupDataMapper.updateById(data);
        }
    }


    public List<HmUserGroupData> listByGroupId(Long groupId) {
        List<HmUserGroupData> userGroupDataDtos = hmUserGroupDataMapper.listByGroupId(groupId);
        return userGroupDataDtos;
    }

    public List<UserGroupDataQuery> getTypeByScopeAndGroupId(String scope, Long groupId) {
        List<HmUserGroupDataPO> userGroupDatas = hmUserGroupDataMapper.selectList(
                new QueryWrapper<HmUserGroupDataPO>()
                        .eq(HmUserGroupDataFields.SCOPE,
                                scope)
                        .eq(HmUserGroupDataFields.USER_GROUP_ID,
                                groupId));
        if (userGroupDatas.isEmpty()) {
            return new ArrayList<>();
        }
        List<Integer> dataTypeIds = userGroupDatas.stream().map(x -> x.getDataTypeId())
                .collect(Collectors.toList());

        List<HmDataTypePO> dataTypes = hmDataTypeRepository.listByIds(dataTypeIds);
        List<UserGroupDataQuery> list = MyBeanUtils.batchTransform(UserGroupDataQuery.class, userGroupDatas);
        for (UserGroupDataQuery dataQueryDto : list) {
            for (HmDataTypePO dataType : dataTypes) {
                if (dataQueryDto.getDataTypeId() == dataType.getId().intValue()) {
                    dataQueryDto.setDataTypeName(dataType.getName());
                    dataQueryDto.setDataTypeCode(dataType.getCode());
                }
            }
        }
        return list;
    }

    public List<String> getUserVals(String scope, String component, Long userId,Long appId) {
        HmDataTypePO dataType = hmDataTypeService.findByCode(appId,component);
        Set<Long> userGroupIdSet=new HashSet<>();

        // Alex 2021年01月13日17:35:40
        // 需要查询出管理员及成员
        List<HmUserGroupManagePO> groupManages = hmUserGroupManageService.selectGroupManageWithUserId(userId);
        List<Long> manageUserGroupIds = groupManages.stream().mapToLong(HmUserGroupManagePO::getUserGroupId).boxed().collect(
                Collectors.toList());
        userGroupIdSet.addAll(manageUserGroupIds);
        // 查询成员
        List<HmUserGroupMemberPO> groupMembers = hmUserGroupMemberService.selectUnDelected();
        //用户类型
        List<Long> userGroupIds = groupMembers.stream().filter(e->e.getIsOrg() == 0&&e.getUnionId().longValue()==userId.longValue()).map(HmUserGroupMemberPO::getUserGroupId).collect(Collectors.toList());
        userGroupIdSet.addAll(userGroupIds);
        //组织结构类型
        List<Long> orgIds = groupMembers.stream().filter(e->e.getIsOrg() == 1).map(HmUserGroupMemberPO::getUnionId).collect(Collectors.toList());

        List<Long> okOrgIds = hmOrgService.userBelongTo(orgIds, userId);

        if(!okOrgIds.isEmpty()){
            List<Long> groupIds = groupMembers.stream().filter(e->e.getIsOrg() == 1&&okOrgIds.contains(e.getUnionId())).map(HmUserGroupMemberPO::getUserGroupId).collect(Collectors.toList());
            userGroupIdSet.addAll(groupIds);
        }
        if(userGroupIdSet.isEmpty()){
            return new ArrayList<>();
        }

        List<HmUserGroupDataPO> userGroupDatas =
                hmUserGroupDataMapper.selectList(
                        new QueryWrapper<HmUserGroupDataPO>()

                                .eq(HmUserGroupDataFields.SCOPE,
                                        scope)
                                .in(HmUserGroupDataFields.USER_GROUP_ID,
                                        userGroupIdSet)
                                .eq(HmUserGroupDataFields.DATA_TYPE_ID, dataType.getId()));

        return userGroupDatas.stream().filter(e-> !StringUtil.isEmpty(e.getVal())).map(HmUserGroupDataPO::getVal).collect(Collectors.toList());
    }

    /**
     * 插入唯一的数据权限
     */
    private void insertSingleGroupData(HmUserGroupDataPO userGroupData) {
        List<HmUserGroupDataPO> userGroupDatas =
                hmUserGroupDataMapper.selectList(
                        new QueryWrapper<HmUserGroupDataPO>()
                                .eq(HmUserGroupDataFields.VAL,
                                        userGroupData.getVal())
                                .eq(HmUserGroupDataFields.SCOPE,
                                        userGroupData.getScope())
                                .eq(HmUserGroupDataFields.USER_GROUP_ID,
                                        userGroupData.getUserGroupId())
                                .eq(HmUserGroupDataFields.DATA_TYPE_ID, userGroupData.getDataTypeId()));
        if (CollectionUtils.isEmpty(userGroupDatas)) {
            hmUserGroupDataMapper.insert(userGroupData);
        }
    }

}